/*
 * common.h
 *
 *  Created on: 2021年7月25日
 *      Author: Administrator
 * description: 实现一些公共函数
 */

#ifndef __COMMON_H_
#define __COMMON_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>

/**
 * 双向链表节点
 */
struct list_node{
    struct list_node *prev; /* 指向上一个节点 */
    struct list_node *next; /* 指向下一个节点 */
};
typedef struct list_node list_t;

/**
 * 初始化链表节点
 *
 * @param node 链表节点；可以是链表头，可以是普通节点
 *
 * @return 无
 */
static inline void list_init(list_t *node)
{
    node->next = node->prev = node;
}

/*
 * 在节点list的后面插入一个节点
 *
 * @param list 一个链表节点；一般是链表头，也可以是普通节点，如果为链表头则是在链表开头插入一个节点
 * @param node 插入的新节点
 *
 * @return 无
 */
static inline void list_insert_after(list_t *list, list_t *node)
{
    list->next->prev = node;
    node->next = list->next;
    
    list->next = node;
    node->prev = list;
}

/*
 * 在节点list的前面插入一个节点
 *
 * @param list 一个链表节点；一般是链表头，也可以是普通节点，如果为链表头则是在链表尾部插入一个节点
 * @paramn 插入的新节点
 *
 * @return  无
 */
static inline void list_insert_before(list_t *list, list_t *node)
{
    list->prev->next = node;
    node->prev = list->prev;
    
    list->prev = node;
    node->next = list;
}

/*
 * 将节点从某个链表中删除
 *
 * @param node 要删除的节点，不能是链表头
 *
 * @return 无
 */
static inline void list_remove(list_t *node)
{
    node->next->prev =node->prev;
    node->prev->next = node->next;
    
    node->next = node->prev = node;
}

/*
 * 判断链表是否为空
 *
 * @param list 一个链表节点；一般是链表头，也可以是普通节点，如果是普通节点则是判断该节点是否孤立
 *
 * @return 空返回 1，非空返回 0
 */
static inline int32_t list_isempty(const list_t *list)
{
    return list->next == list ? 1 : 0;
}

/*
 * 获取链表长度
 *
 * @param list 一个链表节点；一般是链表头
 *
 * @return 返回链表长度
 */
static inline int32_t list_length(const list_t *list)
{
    int32_t length = 0;
    const list_t *tmp = list;
    
    while(tmp->next != list) {
        tmp = tmp->next;
        length++;
    }
    
    return length;
}

/**
 *  链表节点静态初始化
 *
 * @param list 链表节点；可以是链表头，可以是普通节点
 *
 * @return 无
 */
#define LIST_INIT(list) {&(list), &(list)}

/*
 * 功能：
 *      实现链表的遍历
 *
 * @param tmp 用于循环的中间变量，每次遍历到的节点都通过该指针获取
 * @param list 链表头
 *
 * @return 该宏定义用于简化链表的遍历
 */
#define list_for_each(tmp, list) \
    for (tmp = (list)->next; tmp != (list); tmp = tmp->next)

/**
 * 功能：
 *      根据成员地址、结构体类型、成员名查找对应结构体地址
 * @param ptr 成员变量地址
 * @param type 结构体数据类型
 * @param member 成员名称
 *
 * @return 成员所在结构体的地址
 */
#ifndef container_of
#define container_of(ptr, type, member) \
    ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
#endif

int32_t find_first_set(uint32_t value);

#ifdef __cplusplus
}
#endif

#endif /* __COMMON_H_ */
